using System;
using System.Collections.Generic;

namespace CastleSample.UI.Core
{
    /// <summary>
    /// Agent between the event publisher and handler.
    /// </summary>
    public class EventBroker : IEventBroker
    {
        private Dictionary<string, List<EventHandler<ContainerEventArgs>>> m_AllEventHandler =
            new Dictionary<string, List<EventHandler<ContainerEventArgs>>>();

        private Dictionary<string, List<EventHandler<ContainerEventArgs>>> m_AllAsyncEventHandler =
            new Dictionary<string, List<EventHandler<ContainerEventArgs>>>();

        /// <summary>
        /// Register a handler to a named event.
        /// </summary>
        public virtual void RegisterEventHandler(string key, EventHandler<ContainerEventArgs> handler)
        {
            if (!m_AllEventHandler.ContainsKey(key))
            {
                m_AllEventHandler.Add(key, new List<EventHandler<ContainerEventArgs>>());
            }
            if (m_AllEventHandler[key] == null)
            {
                m_AllEventHandler[key] = new List<EventHandler<ContainerEventArgs>>();
            }
            if (!m_AllEventHandler[key].Contains(handler))
            {
                m_AllEventHandler[key].Add(handler);
            }
        }

        /// <summary>
        /// Register a async handler to a named event.
        /// </summary>
        public virtual void RegisterAsyncEventHandler(string key, EventHandler<ContainerEventArgs> handler)
        {
            if (!m_AllAsyncEventHandler.ContainsKey(key))
            {
                m_AllAsyncEventHandler.Add(key, new List<EventHandler<ContainerEventArgs>>());
            }
            if (m_AllAsyncEventHandler[key] == null)
            {
                m_AllAsyncEventHandler[key] = new List<EventHandler<ContainerEventArgs>>();
            }
            if (!m_AllAsyncEventHandler[key].Contains(handler))
            {
                m_AllAsyncEventHandler[key].Add(handler);
            }
        }

        /// <summary>
        /// Publish a event
        /// </summary>
        public virtual void PublishEvent(string key, object sender, ContainerEventArgs arg)
        {
            if (!m_AllEventHandler.ContainsKey(key) || m_AllEventHandler[key] == null)
            {
                return;
            }
            foreach (EventHandler<ContainerEventArgs> handler in m_AllEventHandler[key])
            {
                handler(sender, arg);
            }
            if (!m_AllAsyncEventHandler.ContainsKey(key) || m_AllAsyncEventHandler[key] == null)
            {
                return;
            }
            foreach (EventHandler<ContainerEventArgs> handler in m_AllAsyncEventHandler[key])
            {
                handler.BeginInvoke(sender, arg, null, null);
            }
        }
    }
}